#!/usr/bin/env python3
import sys
import re
import math
import random
from dataclasses import dataclass

MIN = int(sys.argv[1]) if len(sys.argv) > 1 else 1
MAX = int(sys.argv[2]) if len(sys.argv) > 2 else 10
PLAYERS = int(sys.argv[3]) if len(sys.argv) > 3 else 2

@dataclass
class Person:
    pos: int
    points: int = 0

@dataclass
class Board:
    players: list[Person]
    turn: int = 1
    deterministic_die: int = 0
    dice_rolls: int = 0

    def has_winner(self):
        return len([p for p in players if p.points >= 1000]) > 0
    
    def losing_player(self):
        return [ (i + 1, p) for i, p in enumerate(self.players) if p.points == min([p.points for p in self.players]) ][0]

    def roll(self):
        self.dice_rolls += 1
        self.deterministic_die = self.deterministic_die % 100 + 1
        return self.deterministic_die
    
    def simulate_turn(self):
        print(f'simulating turn {self.turn}')
        for i, player in enumerate(self.players):
            for j in range(3):
                roll = self.roll()

                # too lazy to figure out a smarter way
                prev = player.pos
                while roll > 0:
                    roll -= 1
                    player.pos += 1
                    if player.pos > MAX:
                        player.pos = MIN

                print(f'player {i + 1} rolls {roll} and goes from {prev} to {player.pos}')

                if j == 2:
                    print(f'player {i + 1} has new points {player.points} + {player.pos} = {player.pos + player.points}')
                    player.points += player.pos
                    if player.points >= 1000:
                        print(f'player {i + 1} has won')
                        return True
        self.turn += 1
        return False

players = [ Person(random.randint(MIN, MAX - 1)) for _ in range(PLAYERS) ]
players = [ Person(4), Person(8) ]
board = Board(players)
print(board)
while not board.simulate_turn():
    pass
losing_player = board.losing_player()
print(f'{board.dice_rolls} dice rolls, with losing player {losing_player}, making for an end result of {board.dice_rolls * losing_player[1].points}')